package com.example.service_vod.service.impl;

import com.aliyun.tea.TeaException;
import com.aliyun.vod.upload.impl.UploadVideoImpl;
import com.aliyun.vod.upload.req.UploadStreamRequest;
import com.aliyun.vod.upload.resp.UploadStreamResponse;
import com.aliyun.vod20170321.models.GetPlayInfoResponse;
import com.aliyun.vod20170321.models.GetPlayInfoResponseBody;
import com.aliyun.vod20170321.models.GetVideoPlayAuthResponse;
import com.example.common.exception.GuliException;
import com.example.service_vod.service.VodService;
import com.example.service_vod.util.VodConstantUtils;
import com.example.service_vod.util.VodUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @Author:tjf
 * @Description:
 */
@Service
public class VodServiceImpl implements VodService {
    /**
     * 视频上传
     *
     * @param file
     */
    @Override
    public String uploadVideo(MultipartFile file) {
        String title = UUID.randomUUID().toString();
        String fileName = file.getOriginalFilename();
        try {
            String videoId = this.uploadStream(VodConstantUtils.ACCESS_KEY_ID, VodConstantUtils.ACCESS_KEY_SECRET, title, fileName, file.getInputStream());
            return videoId;
        } catch (Exception e) {
            throw new GuliException(20001, "文件上传失败");
        }
    }

    /**
     * 根据视频id，删除视频
     *
     * @param videoId
     */
    @Override
    public void removeVideoById(String videoId) {
        try {
            this.removeVideo(VodConstantUtils.ACCESS_KEY_ID, VodConstantUtils.ACCESS_KEY_SECRET, videoId);
        } catch (Exception e) {
            throw new GuliException(20001, "删除视频失败");
        }
    }

    @Override
    public String fetchVideoPlayAuth(String vSourceId) {
        // 获取视频的播放凭证
        if (StringUtils.isNotBlank(vSourceId)){
            String playAuth = fetchVideoPlayAuth(VodConstantUtils.ACCESS_KEY_ID,
                                            VodConstantUtils.ACCESS_KEY_SECRET, vSourceId);
            return playAuth;
        }
        throw new GuliException(20001, "获取视频播放凭证失败！");
    }
    /**
     * 流式上传接口
     *
     * @param accessKeyId
     * @param accessKeySecret
     * @param title
     * @param fileName
     * @param inputStream
     */
    private String uploadStream(String accessKeyId, String accessKeySecret, String title, String fileName, InputStream inputStream) {
        String videoId = null;
        UploadStreamRequest request = new UploadStreamRequest(accessKeyId, accessKeySecret, title, fileName, inputStream);
        /* 视频分类ID(可选) */
        request.setCateId(1000542913L);
        /* 存储区域(可选) */
        request.setStorageLocation(VodConstantUtils.VIDEO_STORAGE_LOCATION);
        UploadVideoImpl uploader = new UploadVideoImpl();
        UploadStreamResponse response = uploader.uploadStream(request);
        if (response.isSuccess()) {
            videoId = response.getVideoId();
        } else { //如果设置回调URL无效，不影响视频上传，可以返回VideoId同时会返回错误码。其他情况上传失败时，VideoId为空，此时需要根据返回错误码分析具体错误原因
            System.out.print("VideoId=" + response.getVideoId() + "\n");
            System.out.print("ErrorCode=" + response.getCode() + "\n");
            System.out.print("ErrorMessage=" + response.getMessage() + "\n");
            videoId = response.getVideoId();
        }
        return videoId;
    }

    /**
     * 删除已上传视频的方法
     *
     * @param accessKeyId
     * @param accessKeySecret
     * @param videoId
     * @throws Exception
     */
    private void removeVideo(String accessKeyId, String accessKeySecret, String videoId) throws Exception {
        com.aliyun.vod20170321.Client client = VodUtils.createClient(accessKeyId, accessKeySecret);
        com.aliyun.vod20170321.models.DeleteVideoRequest deleteVideoRequest = new com.aliyun.vod20170321.models.DeleteVideoRequest()
                .setVideoIds(videoId);
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        try {
            client.deleteVideoWithOptions(deleteVideoRequest, runtime);
        } catch (Exception e) {
            // 错误 message
            System.out.println(e.getMessage());
            throw new GuliException(20001, "删除视频失败！");
        }
    }

    /**
     * 向阿里云vod服务请求视频的播放凭证
     *
     * @param accessKeyId
     * @param accessKeySecret
     * @param vSourceId
     * @return
     */
    private static String fetchVideoPlayAuth(String accessKeyId, String accessKeySecret, String vSourceId) {
        try {
            com.aliyun.vod20170321.Client client = VodUtils.createClient(accessKeyId, accessKeySecret);

            com.aliyun.vod20170321.models.GetVideoPlayAuthRequest getVideoPlayAuthRequest =
                    new com.aliyun.vod20170321.models.GetVideoPlayAuthRequest().setVideoId(vSourceId);

            com.aliyun.teautil.models.RuntimeOptions runtime =
                    new com.aliyun.teautil.models.RuntimeOptions();

            // 请求视频播放信息
            GetVideoPlayAuthResponse response = client.getVideoPlayAuthWithOptions
                                                                (getVideoPlayAuthRequest, runtime);

            // 判断视频的状态，若正常则返回播放凭证
            if ("Normal".equals(response.getBody().getVideoMeta().getStatus())) {
                return response.getBody().getPlayAuth();
            }else{
                throw new GuliException(20001, "视频状态异常...");
            }
        } catch (Exception error) {
            throw new GuliException(20001, "获取视频播放凭证失败，原因：" + error.getMessage());
        }
    }
}
